Imports System
Imports System.Data
Imports System.Collections
Imports System.Collections.Generic

Imports Framework

<Serializable(), CLSCompliant(True)> _
Partial Public Class CContent
    Inherits CBaseDynamicM2M
    Implements IComparable(Of CContent)

#Region "Constructors"
    'Public (Copy Constructor)
    Public Sub New(ByVal original as CContent, target As CDataSrc)
        m_dataSrc = target
        m_contentSetId = original.ContentSetId
        m_contentTemplateId = original.ContentTemplateId
        m_contentText = original.ContentText
        m_contentMD5 = original.ContentMD5
        m_contentCreated = original.ContentCreated
        m_contentModified = original.ContentModified
    End Sub

    'Protected (Datareader/Dataset)
    Protected Sub New(ByVal dataSrc As CDataSrc, ByVal dr As IDataReader)
        MyBase.New(dataSrc, dr)
    End Sub
    Protected Sub New(ByVal dataSrc As CDataSrc, ByVal dr As DataRow)
        MyBase.New(dataSrc, dr)
    End Sub
#End Region

#Region "Default Values"
    Protected Overrides Sub InitValues_Auto()
        'Null-Equivalent values (except String.Empty, as nulls tend to be inconvenient for string types)
        m_contentSetId = Integer.MinValue
        m_contentTemplateId = Integer.MinValue
        m_contentText = String.Empty
        m_contentMD5 = Guid.Empty
        m_contentCreated = DateTime.MinValue
        m_contentModified = DateTime.MinValue
    End Sub
#End Region

#Region "Members"
    Protected m_contentSetId As Integer
    Protected m_contentTemplateId As Integer
    Protected m_contentText As String
    Protected m_contentMD5 As Guid
    Protected m_contentCreated As DateTime
    Protected m_contentModified As DateTime
#End Region

#Region "Properties - Column Values"
    'Primary Key Columns
    Public Property [ContentSetId]() As Integer
        Get
            Return m_contentSetId
        End Get
        Set(ByVal value As Integer)
            m_contentSetId = value
        End Set
    End Property
    Public Property [ContentTemplateId]() As Integer
        Get
            Return m_contentTemplateId
        End Get
        Set(ByVal value As Integer)
            m_contentTemplateId = value
        End Set
    End Property

    'Table Columns
    Public Property [ContentText]() As String
        Get
            Return m_contentText
        End Get
        Set(ByVal value As String)
            m_contentText = value
        End Set
    End Property
    Public Property [ContentMD5]() As Guid
        Get
            Return m_contentMD5
        End Get
        Set(ByVal value As Guid)
            m_contentMD5 = value
        End Set
    End Property
    Public Property [ContentCreated]() As DateTime
        Get
            Return m_contentCreated
        End Get
        Set(ByVal value As DateTime)
            m_contentCreated = value
        End Set
    End Property
    Public Property [ContentModified]() As DateTime
        Get
            Return m_contentModified
        End Get
        Set(ByVal value As DateTime)
            m_contentModified = value
        End Set
    End Property

    'View Columns

#End Region

#Region "MustOverride Methods"
    'Schema Information
    Public Const TABLE_NAME As String = "CodeGen_Contents"
    Public Const VIEW_NAME As String  = ""          'Used to override Me.ViewName
    Public Const ORDER_BY_COLS As String = "" 'See the CompareTo method below (Sql-based sorting should match In-Memory sorting)
    Public Const SORTING_COLUMN As String = ""
    Public Overrides ReadOnly Property TableName() As String
        Get
            Return TABLE_NAME
        End Get
    End Property
    Protected Overrides ReadOnly Property OrderByColumns() As String
        Get
            Return ORDER_BY_COLS
        End Get
    End Property

    'CompareTo Interface (Default Sort Order)
    Public Function CompareTo(other As CContent) As Integer Implements IComparable(Of CContent).CompareTo
		Return Me.Template.TemplateName.CompareTo(other.Template.TemplateName)
	End Function

    'Primary Key Information
    Protected Overrides ReadOnly Property PrimaryKeyName() As String
        Get
            Return "ContentSetId"
        End Get
    End Property
    Protected Overrides ReadOnly Property SecondaryKeyName() As String
        Get
            Return "ContentTemplateId"
        End Get
    End Property
    Protected Overrides Property PrimaryKeyValue() As Object
        Get
            Return m_contentSetId
        End Get
        Set(ByVal value As Object)
            m_contentSetId = CType(Value, Integer)
        End Set
    End Property
    Protected Overrides Property SecondaryKeyValue() As Object
        Get
            Return m_contentTemplateId
        End Get
        Set(ByVal value As Object)
            m_contentTemplateId = CType(Value, Integer)
        End Set
    End Property

    'Factory Methods - Object
    Protected Overrides Function MakeFrom(ByVal row As DataRow) As CBase
        Return New CContent(Me.DataSrc, row)
    End Function
    Protected Overrides Function MakeFrom(ByVal dr As IDataReader) As CBase
        Return New CContent(Me.DataSrc, dr)
    End Function
    
    'Factory Methods - List
    Protected Overrides Function MakeList() As IList
        Return New CContentList
    End Function
    Protected Overrides Function MakeList(ByVal capacity As Integer) As IList
        Return New CContentList(capacity)
    End Function

    'Convert from ADO to .Net
    Protected Overrides Sub ReadColumns(ByVal dr As IDataReader)
        m_contentSetId = CAdoData.GetInt(dr, "ContentSetId")
        m_contentTemplateId = CAdoData.GetInt(dr, "ContentTemplateId")
        m_contentText = CAdoData.GetStr(dr, "ContentText")
        m_contentMD5 = CAdoData.GetGuid(dr, "ContentMD5")
        m_contentCreated = CAdoData.GetDate(dr, "ContentCreated")
        m_contentModified = CAdoData.GetDate(dr, "ContentModified")
    End Sub
    Protected Overrides Sub ReadColumns(ByVal dr As DataRow)
        m_contentSetId = CAdoData.GetInt(dr, "ContentSetId")
        m_contentTemplateId = CAdoData.GetInt(dr, "ContentTemplateId")
        m_contentText = CAdoData.GetStr(dr, "ContentText")
        m_contentMD5 = CAdoData.GetGuid(dr, "ContentMD5")
        m_contentCreated = CAdoData.GetDate(dr, "ContentCreated")
        m_contentModified = CAdoData.GetDate(dr, "ContentModified")
    End Sub

    'Parameters for Insert/Update    
    Protected Overrides Function ColumnNameValues() As CNameValueList
        Dim data As New CNameValueList
        data.Add("ContentSetId", NullVal(m_contentSetId))
        data.Add("ContentTemplateId", NullVal(m_contentTemplateId))
        data.Add("ContentText", NullVal(m_contentText))
        data.Add("ContentMD5", NullVal(m_contentMD5))
        data.Add("ContentCreated", NullVal(m_contentCreated))
        data.Add("ContentModified", NullVal(m_contentModified))
        Return data
    End Function
#End Region

#Region "Queries - SelectAll/SelectWhere (inherited methods, cast only)"
    'Select Queries - Non-Paged
    Public Shadows Function SelectAll() As CContentList
        Return CType(MyBase.SelectAll(), CContentList)
    End Function
    Public Shadows Function SelectAll(ByVal orderBy As String) As CContentList
        Return CType(MyBase.SelectAll(orderBy), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal colName As String, ByVal sign As ESign, ByVal colValue As Object) As CContentList
        Return CType(MyBase.SelectWhere(colName, sign, colValue), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteria) As CContentList
        Return CType(MyBase.SelectWhere(where), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteriaList) As CContentList
        Return CType(MyBase.SelectWhere(where), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteriaList, ByVal tableNameOrJoinExpression As String) As CContentList
        Return CType(MyBase.SelectWhere(where, tableNameOrJoinExpression, Me.OrderByColumns), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteriaList, ByVal tableNameOrJoinExpression As String, ByVal orderBy As String) As CContentList
        Return CType(MyBase.SelectWhere(where, tableNameOrJoinExpression, orderBy), CContentList)
    End Function
    <Obsolete("Arbitrary where-clause is not necessary portable or safe from sql injection attacks. Consider using the parameterised query interfaces")> _
    Protected Shadows Function SelectWhere(ByVal unsafeWhereClause As String) As CContentList
        Return CType(MyBase.SelectWhere(unsafeWhereClause), CContentList)
    End Function
    Protected Shadows Function SelectById(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer) As CContentList
        Return CType(MyBase.SelectById(contentSetId, contentTemplateId), CContentList)
    End Function
    Protected Shadows Function SelectByIds(ByVal ids As List(Of Integer)) As CContentList
        Return CType(MyBase.SelectByIds(ids), CContentList)
    End Function

    'Select Queries - Paged
    Public Shadows Function SelectAll(ByVal pi As CPagingInfo) As CContentList
        Return CType(MyBase.SelectAll(pi), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal colName As String, ByVal sign As ESign, ByVal colValue As Object) As CContentList
        Return CType(MyBase.SelectWhere(pi, colName, sign, colValue), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal criteria As CCriteria) As CContentList
        Return CType(MyBase.SelectWhere(pi, criteria), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal criteria As CCriteriaList) As CContentList
        Return CType(MyBase.SelectWhere(pi, criteria), CContentList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal criteria As CCriteriaList, ByVal tableViewOrJoinExpr As String) As CContentList
        Return CType(MyBase.SelectWhere(pi, criteria, tableViewOrJoinExpr), CContentList)
    End Function
    Protected Shadows Function SelectByIds(ByVal pi As CPagingInfo, ByVal ids As List(Of Integer)) As CContentList
        Return CType(MyBase.SelectByIds(pi, ids), CContentList)
    End Function

    'Select Queries - Transactional (Friend-scoped for use in cascade-deletes)
    Friend Shadows Function SelectAll(ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectAll(tx), CContentList)
    End Function
    Friend Shadows Function SelectWhere(ByVal columnName As String, columnValue As Object, ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectWhere(columnName, columnValue, tx), CContentList)
    End Function
    Friend Shadows Function SelectWhere(ByVal columnName As String, sign As ESign, columnValue As Object, ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectWhere(columnName, sign, columnValue, tx), CContentList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteria, ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectWhere(criteria, tx), CContentList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteriaList, ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectWhere(criteria, tx), CContentList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteriaList, ByVal tableOrJoin As String, ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectWhere(criteria, tableOrJoin, tx), CContentList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteriaList, ByVal tableOrJoin As String, ByVal orderBy As String, ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectWhere(criteria, tableOrJoin, orderBy, tx), CContentList)
    End Function
    Friend Shadows Function SelectById(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer, ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectById(contentSetId, contentTemplateId, tx), CContentList)
    End Function
    Friend Shadows Function SelectByIds(ByVal ids As List(Of Integer), ByVal tx As IDbTransaction) As CContentList
        Return CType(MyBase.SelectByIds(ids, tx), CContentList)
    End Function
    
    'Select Queries - Stored Procedures
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal txOrNull As IDbTransaction) As CContentList
        Return CType(MyBase.MakeList(storedProcName,         txOrNull), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal params As Object(), ByVal txOrNull As IDbTransaction) As CContentList
        Return CType(MyBase.MakeList(storedProcName, params, txOrNull), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal params As CNameValueList, ByVal txOrNull As IDbTransaction) As CContentList
        Return CType(MyBase.MakeList(storedProcName, params, txOrNull), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal params As List(Of Object), ByVal txOrNull As IDbTransaction) As CContentList
        Return CType(MyBase.MakeList(storedProcName, params, txOrNull), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal param1 As Integer, ByVal txOrNull As IDbTransaction) As CContentList
        Return CType(MyBase.MakeList(storedProcName, param1, txOrNull), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal param1 As String, ByVal txOrNull As IDbTransaction) As CContentList
        Return CType(MyBase.MakeList(storedProcName, param1, txOrNull), CContentList)
    End Function

    'Query Results
    Protected Overloads Function MakeList(ByVal ds As DataSet) As CContentList
        Return CType(MyBase.MakeList(ds), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal dt As DataTable) As CContentList
        Return CType(MyBase.MakeList(dt), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal rows As DataRowCollection) As CContentList
        Return CType(MyBase.MakeList(rows), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal dr As IDataReader) As CContentList
        Return CType(MyBase.MakeList(dr), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal drOrDs As Object) As CContentList
        Return CType(MyBase.MakeList(drOrDs), CContentList)
    End Function
    Protected Overloads Function MakeList(ByVal gzip As Byte()) As CContentList
        Return CType(MyBase.MakeList(gzip), CContentList)
    End Function
#End Region

#Region "Queries - SelectBy[FK] (user-nominated fk/bool columns)"
    'Note: These methods should only be used for cascade-deletes, or initialising the cache. Use CContent.Cache.GetBy... for reqular queries
    
    'Non-Paged
    Protected Function SelectByMD5(ByVal contentMD5 As Guid) As CContentList
        Return SelectWhere(new CCriteriaList("ContentMD5", contentMD5))
    End Function
    Protected Function SelectBySetId(ByVal contentSetId As Integer) As CContentList
        Return SelectWhere(new CCriteriaList("ContentSetId", contentSetId))
    End Function
    Protected Function SelectByTemplateId(ByVal contentTemplateId As Integer) As CContentList
        Return SelectWhere(new CCriteriaList("ContentTemplateId", contentTemplateId))
    End Function

    'Paged
    Protected Function SelectByMD5(pi as CPagingInfo, ByVal contentMD5 As Guid) As CContentList
        Return SelectWhere(pi, New CCriteriaList("ContentMD5", contentMD5))
    End Function
    Protected Function SelectBySetId(pi as CPagingInfo, ByVal contentSetId As Integer) As CContentList
        Return SelectWhere(pi, New CCriteriaList("ContentSetId", contentSetId))
    End Function
    Protected Function SelectByTemplateId(pi as CPagingInfo, ByVal contentTemplateId As Integer) As CContentList
        Return SelectWhere(pi, New CCriteriaList("ContentTemplateId", contentTemplateId))
    End Function

    'Count
    Protected Function SelectCountByMD5(ByVal contentMD5 As Guid) As Integer
        Return SelectCount(New CCriteriaList("ContentMD5", contentMD5))
    End Function
    Protected Function SelectCountBySetId(ByVal contentSetId As Integer) As Integer
        Return SelectCount(New CCriteriaList("ContentSetId", contentSetId))
    End Function
    Protected Function SelectCountByTemplateId(ByVal contentTemplateId As Integer) As Integer
        Return SelectCount(New CCriteriaList("ContentTemplateId", contentTemplateId))
    End Function

    'Transactional
    Friend Function SelectByMD5(ByVal contentMD5 As Guid, tx As IDbTransaction) As CContentList
        Return SelectWhere(New CCriteriaList("ContentMD5", contentMD5), tx)
    End Function
    Friend Function SelectBySetId(ByVal contentSetId As Integer, tx As IDbTransaction) As CContentList
        Return SelectWhere(New CCriteriaList("ContentSetId", contentSetId), tx)
    End Function
    Friend Function SelectByTemplateId(ByVal contentTemplateId As Integer, tx As IDbTransaction) As CContentList
        Return SelectWhere(New CCriteriaList("ContentTemplateId", contentTemplateId), tx)
    End Function
#End Region

#Region "Many-To-Many Helper Functions"
    'Insert/Delete - NonTransactional
    Public Shared Function InsertPair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer) As Integer
        Return InsertPair(contentSetId, contentTemplateId, Nothing)
    End Function
    Public Shared Function DeletePair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer) As Integer
        Return DeletePair(contentSetId, contentTemplateId, Nothing)
    End Function
    Public Shared Function ExistsPair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer) As Boolean
        Return ExistsPair(contentSetId, contentTemplateId, Nothing)
    End Function
    
    'Insert/Delete - Default Datasrc
    Public Shared Function InsertPair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer, ByVal txOrNull As IDbTransaction) As Integer
        Return InsertPair(contentSetId, contentTemplateId, txOrNull, CDataSrc.Default)
    End Function
    Public Shared Function DeletePair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer, ByVal txOrNull As IDbTransaction) As Integer
        Return DeletePair(contentSetId, contentTemplateId, txOrNull, CDataSrc.Default)
    End Function
    Public Shared Function ExistsPair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer, ByVal txOrNull As IDbTransaction) As Boolean
        Return ExistsPair(contentSetId, contentTemplateId, txOrNull, CDataSrc.Default)
    End Function

    'Insert/Delete - Transactional
    Public Shared Function InsertPair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer, ByVal txOrNull As IDbTransaction, ByVal dataSrc as CDatasrc) As Integer
        With New CContent(dataSrc)
            .ContentSetId = contentSetId
            .ContentTemplateId = contentTemplateId
            .Save(txOrNull)
        End With
    End Function
    Public Shared Function DeletePair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer, ByVal txOrNull As IDbTransaction, ByVal dataSrc as CDatasrc) As Integer
        Dim where As New CCriteriaList()
        where.Add("ContentSetId", contentSetId)
        where.Add("ContentTemplateId", contentTemplateId)

        'Faster, but not audited
        'Return New CContent(dataSrc).DeleteWhere(where, txOrNull)
        
        Dim list As CContentList = New CContent(dataSrc).SelectWhere(where, txOrNull)
        list.DeleteAll(txOrNull)
        return list.Count
    End Function
    Public Shared Function ExistsPair(ByVal contentSetId As Integer, ByVal contentTemplateId As Integer, ByVal txOrNull As IDbTransaction, ByVal dataSrc as CDatasrc) As Boolean
        With New CContent(dataSrc)
            Return .SelectById(contentSetId, contentTemplateId, txOrNull).Count > 0
        End With
    End Function
#End Region

#Region "Static - Cache Implementation"
    Public Shared Property Cache() As CContentList
        Get
            Cache = CType(CCache.Get(CACHE_KEY), CContentList)
            If IsNothing(cache) Then
                SyncLock (CACHE_KEY)
                    Cache = CType(CCache.Get(CACHE_KEY), CContentList)
                    If IsNothing(cache) Then
                        Cache = LoadCache()
                        CContent.Cache = Cache
                    End If
                End SyncLock
            End If
            Return cache
        End Get
        Set(ByVal value As CContentList)
            SetCache(value)
        End Set
    End Property

    'Change Management:
    'Clone, modify, and then replace the cache (threadsafe for anything iterating the collection)
    'Note that internal indices are dicarded each time unless handled in constructor and add/remove overrides
    Protected Overrides Sub CacheDelete()
        If CacheIsNull Then Exit Sub
        SyncLock (CACHE_KEY)
            Dim temp As CContentList = New CContentList(Cache)
            Dim size As Integer = temp.Count
            temp.Remove(Me)
            If size = temp.Count Then 'Remove might fail If cache was refreshed with New instances. Use old index                    
                temp.Remove(CacheGetById(temp))
            End If
            SetCache(temp)
        End SyncLock
    End Sub
    Protected Overrides Sub CacheInsert()
        If CacheIsNull Then Exit Sub
        SyncLock (CACHE_KEY)
            Dim temp As CContentList = New CContentList(Cache)
            temp.Add(Me)
            SetCache(temp)
        End SyncLock
    End Sub
    Protected Overrides Sub CacheUpdate()
        If CacheIsNull Then Exit Sub
        SyncLock (CACHE_KEY)
            Dim temp As CContentList = New CContentList(Cache)
            If Not temp.Contains(Me) Then
                temp.Remove(CacheGetById(temp))
                temp.Add(Me)
            End If
            SetCache(temp)
        End SyncLock
    End Sub
    Protected Overrides Sub CacheClear()
        Cache = Nothing
    End Sub
    Public Shared ReadOnly Property CacheIsNull() As Boolean
        Get
            Return IsNothing(CCache.Get(CACHE_KEY))
        End Get
    End Property
#End Region

#Region "ToXml"
    Protected Overrides Sub ToXml_Autogenerated(ByVal w As System.Xml.XmlWriter)
        Store(w, "ContentSetId", Me.ContentSetId)
        Store(w, "ContentTemplateId", Me.ContentTemplateId)
        Store(w, "ContentText", Me.ContentText)
        Store(w, "ContentMD5", Me.ContentMD5)
        Store(w, "ContentCreated", Me.ContentCreated)
        Store(w, "ContentModified", Me.ContentModified)
    End Sub
#End Region

End Class
